在前一篇文章中,學到了如何在一般的 JavaScript 專案中加入 TypeScript,今天就來分享在前端框架 React.js 如何使用吧!TypeScript 能夠帶來型別檢查的優勢,幫助開發者避免許多在 JavaScript 中常見的錯誤。接下來,我會介紹如何在 React 中設置 TypeScript,以及提供一些簡單易懂的範例。
首先起手是當然是要初始化啦!要開始一個使用 TypeScript 的 React 專案,可以用 Create React App 工具進行初始化。打開終端機中執行以下指令:
npx create-react-app hello-typescript --template typescript
完成後,可能會看到這樣的提示訊息。
這樣的指令會自動建立一個包含 TypeScript 支援的 React 專案。專案結構和傳統的 JavaScript 專案幾乎相同,不過檔案的副檔名會是 .tsx,表示這些檔案可以同時包含 TypeScript 和 JSX 語法。
讓我們來看一個簡單的 React 元件範例。在 TypeScript 中,我們可以使用介面(interface)來定義元件的 props 參數。
// src/components/Greeting.tsx
import React from 'react';
interface GreetingProps {
  name: string;
}
const Greeting: React.FC<GreetingProps> = ({ name }) => {
  return <h1>Hello, {name}!</h1>;
};
export default Greeting;
這個檔案中,我建立了一個 Greeting 元件,它接受一個 name 參數,並在畫面上顯示一個招呼語。接下來用 interface GreetingProps 來定義這個元件所需的 props。React.FC<GreetingProps> 則告訴 TypeScript,這是一個接受 GreetingProps 的函式型元件(Functional Component)。
接下來,可以在頁面裡試著引入上面做好的招呼語元件:
// src/App.tsx
import React from 'react';
import Greeting from './components/Greeting';
function App() {
  return (
    <div className="App">
      <Greeting name="Annie" />
    </div>
  );
}
export default App;
在這個範例中,當忘記傳遞 name 給 Greeting 元件時,TypeScript 會直接在開發時告訴我們發生了錯誤,這就是型別檢查的好處。
接下來的範例,藉由使用 useState 來建立一個計數器,並指定計數的型別為 number。此外,我們用 useEffect 來更新頁面的標題。TypeScript 會自動推斷出 useState 回傳的是一個數字狀態,並檢查 setCount 的調用是否符合數字型別的限制。
import React, { useState, useEffect } from 'react';
const Counter: React.FC = () => {
  const [count, setCount] = useState<number>(0);
  useEffect(() => {
    document.title = `You clicked ${count} times`;
  }, [count]);
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  );
};
export default Counter;
最後,可以把以上的內容綜合運用、延伸前一篇幅的範例,來建構一個簡單的 To-Do List 的 React 應用程式,並在其中充分利用 TypeScript 的型別檢查功能。
import React, { useState } from 'react';
interface Todo {
  id: number;
  task: string;
  completed: boolean;
}
const TodoApp: React.FC = () => {
  const [todos, setTodos] = useState<Todo[]>([]);
  const [task, setTask] = useState<string>('');
  const addTodo = () => {
    const newTodo: Todo = {
      id: todos.length + 1,
      task,
      completed: false,
    };
    setTodos([...todos, newTodo]);
    setTask('');
  };
  return (
    <div>
      <h1>To-Do List</h1>
      <input 
        value={task} 
        onChange={(e) => setTask(e.target.value)} 
        placeholder="Add a task" 
      />
      <button onClick={addTodo}>Add Task</button>
      <ul>
        {todos.map((todo) => (
          <li key={todo.id}>
            {todo.task}
            {todo.completed ? ' (Completed)' : ''}
          </li>
        ))}
      </ul>
    </div>
  );
};
export default TodoApp;
在這個 To-Do List 的範例中,我們定義了一個 Todo 介面來描述每個待辦事項的型別。利用 TypeScript 的型別系統,我們可以確保每個 todo 物件的結構是一致的,並且程式碼執行時更加安全可靠。
在 React 中加入 TypeScript 可以提升開發過程中的錯誤檢查能力,讓專案更具維護性與穩定性。透過這篇文章中的範例,我們展示了如何使用 TypeScript 設定元件、Hook 以及進行型別檢查。隨著專案複雜度的提高,TypeScript 將成為你強大的工具,幫助你寫出更健壯的程式碼。